﻿using Arch.EntityFrameworkCore.UnitOfWork;
using AutoMapper;
using Common.Lib.Dto;
using Common.Lib.Parameter;
using Common.Lib.Service;
using Server.Todo.Context;
using System.Collections.ObjectModel;

namespace Server.Todo.Service
{
    public class ToDoService : IToDoService
    {
        private readonly IUnitOfWork unitOfWork;
        private readonly IMapper mapper;
        private readonly IRepository<ToDo> repository;

        public ToDoService(IUnitOfWork unitOfWork,IMapper mapper)
        {
            this.unitOfWork = unitOfWork;
            this.mapper = mapper;
            this.repository = unitOfWork.GetRepository<ToDo>();
        }

        public async Task<ApiResponse> AddAsync(ToDoDto model)
        {
            try
            {
                var todo = mapper.Map<ToDo>(model);
                await unitOfWork.GetRepository<ToDo>().InsertAsync(todo);
                if (await unitOfWork.SaveChangesAsync() > 0)
                {
                    return new ApiResponse(true, todo);
                }
                return new ApiResponse("添加数据失败");
            }
            catch(Exception ex)
            {
                return new ApiResponse($"添加数据失败:{ex.Message}");
            }
        }

        public async Task<ApiResponse> DeleteAsync(int id)
        {
            try
            {
                var repository = unitOfWork.GetRepository<ToDo>();
                var todo = await repository.GetFirstOrDefaultAsync(predicate: p=>p.Id.Equals(id));
                repository.Delete(todo);

                if (await unitOfWork.SaveChangesAsync() > 0)
                {
                    return new ApiResponse(true,null);
                }
                return new ApiResponse("删除数据失败");
            }
            catch (Exception ex)
            {
                return new ApiResponse($"删除数据失败:{ex.Message}");
            }
        }

        public async Task<ApiResponse> GetAllAsync(QueryParameter queryParameter)
        {
            try
            {
                var repository = unitOfWork.GetRepository<ToDo>();
                var todos = await repository.GetPagedListAsync(
                    predicate: p=> string.IsNullOrEmpty(queryParameter.SearchKey) ?　true : p.Title.Contains(queryParameter.SearchKey),
                    pageSize: queryParameter.PageSize,
                    pageIndex: queryParameter.PageIndex,
                    orderBy:o=>o.OrderByDescending(p=>p.Id)
                    );
                return new ApiResponse(true, todos);
            }
            catch (Exception ex)
            {
                return new ApiResponse($"查询所有数据失败:{ex.Message}");
            }
        }

        public async Task<ApiResponse> GetAllFilterAsync(ToDoQueryParameter queryParameter)
        {
            try
            {
                var repository = unitOfWork.GetRepository<ToDo>();
                var todos = await repository.GetPagedListAsync(

                    predicate: p => 
                    (string.IsNullOrEmpty(queryParameter.SearchKey) ? true : p.Title.Contains(queryParameter.SearchKey)) 
                    && (queryParameter.Status == null ? true: p.Status == queryParameter.Status.GetValueOrDefault()),

                    pageSize: queryParameter.PageSize,
                    pageIndex: queryParameter.PageIndex,
                    orderBy: o => o.OrderByDescending(p => p.Id)
                    );
                return new ApiResponse(true, todos);
            }
            catch (Exception ex)
            {
                return new ApiResponse($"查询所有数据失败:{ex.Message}");
            }
        }

        public async Task<ApiResponse> GetSingleAsync(int id)
        {
            try
            {
                var repository = unitOfWork.GetRepository<ToDo>();
                var todo = await repository.GetFirstOrDefaultAsync(predicate: p=>p.Id.Equals(id));
                return new ApiResponse(true, todo);
            }
            catch (Exception ex)
            {
                return new ApiResponse($"查询单条数据失败:{ex.Message}");
            }
        }

        public async Task<ApiResponse> UpdateAsync(ToDoDto model)
        {
            try
            {
                var todo = mapper.Map<ToDo>(model);
                await unitOfWork.GetRepository<ToDo>().InsertAsync(todo);
                var repository = unitOfWork.GetRepository<ToDo>();
                repository.Update(todo);
                if (await unitOfWork.SaveChangesAsync() > 0)
                {
                    return new ApiResponse(true, model);
                }
                return new ApiResponse("更新数据失败");
            }
            catch (Exception ex)
            {
                return new ApiResponse($"更新数据失败:{ex.Message}");
            }
        }

        public async Task<ApiResponse> SummaryAsync()
        {
            try
            {
                var repository = unitOfWork.GetRepository<ToDo>();
                var todos = await repository.GetAllAsync(
                    orderBy: o => o.OrderByDescending(p => p.Id));

                var memos = await unitOfWork.GetRepository<Memo>().GetAllAsync(
                    orderBy: o => o.OrderByDescending(p => p.Id));

                SummaryDto summaryDto = new SummaryDto();
                summaryDto.TodoList = new ObservableCollection<ToDoDto>(mapper.Map<List<ToDoDto>>(todos.Where(t => t.Status == 0)));
                summaryDto.MemoList = new ObservableCollection<MemoDto>(mapper.Map<List<MemoDto>>(memos));
                summaryDto.MemoCount = summaryDto.MemoList.Count;
                summaryDto.Sum = todos.Count;
                summaryDto.CompletedCount = todos.Where(p => p.Status == 1).Count();
                summaryDto.CompletedRatio = (summaryDto.CompletedCount / (decimal)summaryDto.Sum).ToString("0%") ;

                return new ApiResponse(true, summaryDto);

            }
            catch (Exception ex)
            {
                return new ApiResponse($"查询所有数据失败:{ex.Message}");
            }
        }
    }
}
